import { resetVector } from './reset-data.esm.js';

const vertexShader = `attribute vec3 position3DHigh;
attribute vec3 position3DLow;
attribute float batchId;
attribute vec3 sts;
varying vec3 v_st;

void main() {
  vec4 position = czm_modelViewProjectionRelativeToEye * czm_computePosition();
  v_st = sts;
  gl_Position = position;
}`;

const fragShader = `varying vec3 v_st;

void main() {
   float r = v_st.x; 
   float g = v_st.y; 
   float b = v_st.z;
   gl_FragColor = vec4(r, g, b, 0.5);
}`;

const materialSource = `uniform float speed;

float getSpeed(){
  return speed;
}
`;

class PrimitivePlaneShader {
  /**
   *
   * @param {object} options
   * @param {import('cesium').Viewer} options.viewer
   */
  constructor(options) {
    const { viewer } = options;
    this.viewer = viewer;
    this.customPrimitive = null;
  }

  /**
   *
   * @param {object} inputData 输入数据
   * @param {number[]} inputData.renderData
   * @param {number[]} inputData.triangleData
   * @param {string} fieldName
   * @param {any[]} colorRange
   */
  createPrimitive(inputData, fieldName, colorRange) {
    const options = resetVector(inputData, fieldName, colorRange);
    const sts = new Float32Array(options.sts);
    const positionIndex = new Uint16Array(options.index);
    const positions = options.vectors;

    const geometry = createGeometry(positions, sts, positionIndex);
    const appearance = createAppearance(vertexShader, fragShader);
    this.customPrimitive = this.viewer.scene.primitives.add(
      // @ts-ignore
      new Cesium.Primitive({
        // @ts-ignore
        geometryInstances: new Cesium.GeometryInstance({
          geometry: geometry
        }),
        appearance: appearance,
        asynchronous: false
      })
    );
  }
}

function createAppearance(vertexShader, fragShader) {
  // @ts-ignore
  return new Cesium.Appearance({
    // @ts-ignore
    material: new Cesium.Material({
      fabric: {
        uniforms: {
          speed: 0.1
        },
        source: materialSource
      }
    }),
    // @ts-ignore
    aboveGround: true,
    translucent: false, //显示不为半透明
    renderState: {
      // @ts-ignore
      blending: Cesium.BlendingState.DISABLED, // Cesium.BlendingState.PRE_MULTIPLIED_ALPHA_BLEND,//使用Alpha混合功能启用混合
      depthTest: { enabled: false }, //深度检测
      depthMask: false //将深度值写入深度缓冲区
    },
    fragmentShaderSource: fragShader, //片段着色器
    vertexShaderSource: vertexShader //顶点着色器
  });
}

//构建几何体
function createGeometry(positions, sts, positionIndex) {
  // @ts-ignore
  return new Cesium.Geometry({
    // @ts-ignore
    attributes: {
      //几何顶点属性
      // @ts-ignore
      position: new Cesium.GeometryAttribute({
        // @ts-ignore
        componentDatatype: Cesium.ComponentDatatype.DOUBLE, //数据类型
        componentsPerAttribute: 3, //定义几个为一组
        values: positions //坐标值
      }),
      // @ts-ignore
      sts: new Cesium.GeometryAttribute({
        // @ts-ignore
        componentDatatype: Cesium.ComponentDatatype.FLOAT, //数据类型
        componentsPerAttribute: 3, //定义几个为一组
        values: sts //坐标值
      })
    },
    indices: positionIndex, //顶点索引
    // @ts-ignore
    primitiveType: Cesium.PrimitiveType.TRIANGLES, //图元类型
    // @ts-ignore
    boundingSphere: Cesium.BoundingSphere.fromVertices(positions) //包围球
  });
}

export { PrimitivePlaneShader };
